package com.automation.utils;

import com.automation.entity.*;
import com.automation.service.AppiumUtils;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import io.appium.java_client.android.options.UiAutomator2Options;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.*;

public class MainTest {
    public static AndroidDriver driver;
    private static final String APP_PACKAGE = "com.dianping.v1";
    private static final String APP_ACTIVITY = ".NovaMainActivity";
    private static int processedShops = 0;
    private static final int MAX_SHOPS = 10; // 最大处理商户数

    //    public static void setup() throws MalformedURLException {
//        UiAutomator2Options options = new UiAutomator2Options()
//                .setUdid("emulator-5554") // 设备ID
//                .setAppPackage(APP_PACKAGE)
//                .setAppActivity(APP_ACTIVITY)
//                .setAutoGrantPermissions(true)
//                .setNoReset(false);
//
//        driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
//        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
//    }

    private static final String APPIUM_SERVER_URL = "http://127.0.0.1:4723/wd/hub";

    public static AndroidDriver init() {
        try {
            // 1. 创建选项对象
            UiAutomator2Options options = new UiAutomator2Options();

            // 2. 设置基础能力
            options.setPlatformName("Android");
            options.setPlatformVersion("7.1.2");
            options.setUdid("127.0.0.1:5555"); // 关键：只设置udid
            options.setAutomationName("UiAutomator2");

            // 3. 应用配置
//            options.setAppPackage("com.netease.cloudmusic");
            options.setAppActivity(".activity.MainActivity");

            // 4. 键盘和权限设置
//            options.setUnicodeKeyboard(true);
//            options.setResetKeyboard(true);
            options.setAutoGrantPermissions(true);

            // 5. 会话设置
            options.setNoReset(true);
            options.setNewCommandTimeout(Duration.ofSeconds(3600));
            options.setEnsureWebviewsHavePages(true);
            options.setNativeWebScreenshot(true);
//            options.setConnectHardwareKeyboard(true);

            // 6. 雷电模拟器专用优化
            options.setCapability("systemPort", 8200);
            options.setCapability("unicodeKeyboard", true);  // 启用Unicode输入
            options.setCapability("skipDeviceInitialization", true);
            options.setCapability("skipServerInstallation", true);
            options.setCapability("disableAndroidWatchers", true);

            // 7. 移除冲突的deviceName
            // 不要设置deviceName，它会导致冲突

            // 8. 创建驱动实例（使用新端点）
            AndroidDriver driver = new AndroidDriver(new URL(APPIUM_SERVER_URL), options);
            // 9. 设置隐式等待

            // 10. 验证连接
            System.out.println("设备状态: " + driver.getStatus());
            System.out.println("当前Activity: " + driver.currentActivity());
            return driver;
        } catch (MalformedURLException e) {
            System.err.println("URL格式错误: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("连接失败: " + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        try {
            //执行代码前，先启动
            // 1、adb devices
            // 2、adb connect 127.0.0.1:5555
            // 3、adb kill-server
            // 4、adb start-server
            AndroidDriver init = init();
            driver = init;
            testDianpingAutomation();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testDianpingAutomation() throws Exception {
        // 1. 从桌面启动大众点评
        DesktopPage desktop = new DesktopPage(driver);
        desktop.launchDianping();

        // 2. 首页操作
        HomePage homePage = new HomePage(driver);
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
        }
        homePage.refreshAndWait();
        homePage.openSearch();
        // 等待结果加载
        Thread.sleep(3000);
        // 输入后隐藏键盘
        driver.hideKeyboard();
        // 或通过按返回键
//        driver.pressKey(new KeyEvent(AndroidKey.BACK));

        if (!homePage.isSearchOpened()) {
            throw new RuntimeException("搜索栏未正确打开");
        }
//        contexts = driver.getContextHandles();
//        driver.context((String) contexts.toArray()[1]); // 切换到WEBVIEW上下文
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        WebElement merchantList = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//android.widget.FrameLayout[@content-desc=\"SearchPagerListView-商户\"]")));
        boolean elementPresent = AppiumUtils.isElementPresent(driver, By.xpath("//android.widget.FrameLayout[@content-desc=\"SearchPagerListView-商户\"]"), 15);
        if (!elementPresent){
            return;
        }
        boolean elementPresent1 = AppiumUtils.isElementPresent(driver, By.xpath("//android.widget.FrameLayout[@content-desc=\"gridView_item_wrapper\"]"), 15);
        if (!elementPresent1){
            return;
        }
        List<WebElement> merchants = merchantList.findElements(By.xpath("//android.widget.FrameLayout[@content-desc=\"gridView_item_wrapper\"]"));
        // 3. 遍历商户并提取数据
        List<MerchantInfo> merchantData = new ArrayList<>();
        // 获取所有子项 FrameLayout
        run( wait);
// 定位到 RecyclerView 容器
        List<WebElement> advertisedShopWithScroll = findAdvertisedShopWithScroll(driver);


        Dimension size = driver.manage().window().getSize();
        int startY = (int) (size.height * 0.8);
        int endY = (int) (size.height * 0.2);

        new TouchAction<>(driver)
                .press(PointOption.point(size.width / 2, startY))
                .waitAction(WaitOptions.waitOptions(Duration.ofMillis(500)))
                .moveTo(PointOption.point(size.width / 2, endY)).release()
                .perform();

    }

    public static void findAndClickAdvertisedShop(AndroidDriver driver) {
        // 定位商户列表容器（RecyclerView）
        WebElement shopList = driver.findElement(AppiumBy.xpath(
                "//android.widget.FrameLayout[@content-desc='SearchPagerListView-商户']" +
                        "/android.widget.FrameLayout/android.support.v7.widget.RecyclerView"
        ));

        // 获取所有商户项（FrameLayout）
        List<WebElement> shopItems = shopList.findElements(AppiumBy.className("android.widget.FrameLayout"));

        // 遍历商户项查找广告
        for (WebElement shopItem : shopItems) {
            try {
                // 在商户项内查找包含"广告"的文本元素
                WebElement adTag = shopItem.findElement(AppiumBy.xpath(
                        ".//android.widget.TextView[contains(@text, '广告')]"
                ));

                // 找到广告标签后点击整个商户项
                System.out.println("发现广告商户: " + adTag.getText());
                shopItem.click();
                return; // 点击后退出循环

            } catch (org.openqa.selenium.NoSuchElementException e) {
                // 当前商户无广告标签，继续查找
            }
        }

        System.out.println("未找到含'广告'的商户");
    }

    public static List<WebElement> findAdvertisedShopWithScroll(AndroidDriver driver) {
        Set<String> viewedItems = new HashSet<>();
        Dimension screenSize = driver.manage().window().getSize();
        int centerX = screenSize.width / 2;
        List<WebElement> list= new ArrayList<>();
        // 最大滚动次数
        for (int i = 0; i < 20; i++) {
            if (i == 0){
                continue;
            }

            WebElement listContainer = driver.findElement(AppiumBy.xpath(
                    "//android.support.v7.widget.RecyclerView/android.view.ViewGroup[@index='" + 4 + "']"
            ));

            // 获取所有可点击的列表项
            List<WebElement> listItems = listContainer.findElements(AppiumBy.xpath(
                    ".//android.widget.FrameLayout[@clickable='true']"
            ));

            System.out.println("找到的列表项数量: " + listItems.size());
            listItems.get(0).findElement(By.xpath("//android.widget.FrameLayout[@clickable='true']")).click();

            // 执行滚动（从底部滑动到顶部）
            new TouchAction(driver)
                    .press(PointOption.point(centerX, (int)(screenSize.height * 0.8)))
                    .waitAction(WaitOptions.waitOptions(Duration.ofMillis(800)))
                    .moveTo(PointOption.point(centerX, (int)(screenSize.height * 0.3)))
                    .release()
                    .perform();

            // 等待新内容加载
            try { Thread.sleep(2000); } catch (Exception e) {}
        }
        System.out.println("滚动结束，未找到广告商户");
        return  list;
    }

    // 多维度检测广告标记
    public static WebElement isAdMerchant(WebElement merchant) {
        // 方式1: 特定文本检测
        try {
            WebElement adText = merchant.findElement(
                    By.xpath(".//*[contains(@text, '广告') or contains(@text, 'Promoted')]")
            );
            return adText;
        } catch (NoSuchElementException e) {
        }

        // 方式2: 特定图标检测
        try {
            WebElement adIcon = merchant.findElement(
                    By.xpath(".//*[contains(@content-desc, 'ad') or contains(@resource-id, 'ad_marker')]")
            );
            return adIcon;
        } catch (NoSuchElementException e) {
        }

        // 方式3: 特殊样式检测 (如角标、边框)
        String bgColor = merchant.getCssValue("background-color");
        if (bgColor.equals("#FFFDE7") || bgColor.equals("rgba(255, 253, 231, 1)")) {
            return null; // 广告商户特殊背景色
        }

        return null;
    }

    // 提取更多商户信息
    public MerchantInfo extractMerchantInfo(WebElement merchant) {
        MerchantInfo info = new MerchantInfo();

        // 基础信息
        info.setName(getTextSafe(merchant, "com.dianping.v1:id/tv_title"));
        info.setRating(getTextSafe(merchant, "com.dianping.v1:id/tv_comment_score"));
        info.setReviewCount(getTextSafe(merchant, "com.dianping.v1:id/tv_comment_count"));

        // 价格信息
        try {
            info.setPrice(merchant.findElement(
                    By.id("com.dianping.v1:id/tv_price")
            ).getText().replace("¥", ""));
        } catch (Exception e) {
            info.setPrice("未知");
        }

        // 广告检测
        WebElement adMerchant = isAdMerchant(merchant);
        if (null != adMerchant) {
            info.setHasAd(true);
        }
        return info;
    }

    private String getTextSafe(WebElement parent, String id) {
        try {
            return parent.findElement(By.id(id)).getText();
        } catch (Exception e) {
            return "";
        }
    }

    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }




    public static void run(WebDriverWait wait) {
        // 1. 确保在商户列表页面
        wait.until(ExpectedConditions.presenceOfElementLocated(
                AppiumBy.className("android.support.v7.widget.RecyclerView")
        ));

        while (processedShops < MAX_SHOPS) {
            // 2. 定位商户列表容器
            WebElement shopListContainer = findShopListContainer();

            // 3. 获取当前页商户项
            List<WebElement> shopItems = getCurrentPageShopItems(shopListContainer);
            if (shopItems.isEmpty()) break;

            // 4. 遍历商户
            for (WebElement shopItem : shopItems) {
                if (processedShops >= MAX_SHOPS) break;

                // 5a. 点击商户项
                shopItem.click();
                processShopDetail(wait);
                processedShops++;
            }

            // 6. 滚动加载更多
            scrollToLoadMore(shopListContainer);
        }
    }

    private static WebElement findShopListContainer() {
        // 通过特征定位商户列表RecyclerView（高度最大）
        List<WebElement> recyclers = driver.findElements(
                AppiumBy.className("android.support.v7.widget.RecyclerView")
        );

        WebElement maxHeightRecycler = null;
        int maxHeight = 0;

        for (WebElement recycler : recyclers) {
            Dimension size = recycler.getSize();
            if (size.getHeight() > maxHeight) {
                maxHeight = size.getHeight();
                maxHeightRecycler = recycler;
            }
        }
        return maxHeightRecycler;
    }

    private static List<WebElement> getCurrentPageShopItems(WebElement container) {
        // 获取直接子元素（商户项）
        return container.findElements(AppiumBy.xpath("./*"));
    }

    private static void processShopDetail(WebDriverWait wait) {
        // 5b. 等待详情页加载
        wait.until(ExpectedConditions.presenceOfElementLocated(
                AppiumBy.xpath("//*[contains(@text, '商家信息') or contains(@text, '评分')]")
        ));
        test();
        // 5c. 停留查看
        sleep(3000);

        // 5d. 进入评价页
        try {
            driver.findElement(AppiumBy.xpath("//*[contains(@text, '评价')]")).click();
            processReviews( wait);
        } catch (Exception e) {
            System.out.println("未找到评价页入口");
        }

        // 5i. 返回列表
        driver.pressKey(new KeyEvent(AndroidKey.BACK));
        wait.until(ExpectedConditions.presenceOfElementLocated(
                AppiumBy.className("android.support.v7.widget.RecyclerView")
        ));
    }

    private static void processReviews(WebDriverWait wait) {
        // 5d. 等待评价页加载
        wait.until(ExpectedConditions.presenceOfElementLocated(
                AppiumBy.xpath("//*[contains(@text, '带图') or contains(@text, '视频')]")
        ));

        // 5e. 筛选带图/视频评价
        try {
            driver.findElement(AppiumBy.xpath("//*[contains(@text, '带图')]")).click();
            sleep(2000);
            driver.findElement(AppiumBy.xpath("//*[contains(@text, '视频')]")).click();
            sleep(2000);
        } catch (Exception e) {
            System.out.println("未找到筛选选项");
        }

        // 5f. 检测并保存高质量图片（模拟）
        System.out.println("检测到高质量图片，已保存");

        // 5g. 创建笔记（模拟）
        driver.findElement(AppiumBy.id("com.dianping.v1:id/create_note_btn")).click();
        sleep(1500);
        driver.findElement(AppiumBy.xpath("//*[contains(@text, '推荐拼图')]")).click();
        driver.findElement(AppiumBy.xpath("//*[contains(@text, '火锅')]")).click();

        // 5h. 保存草稿
        driver.findElement(AppiumBy.id("com.dianping.v1:id/save_draft_btn")).click();
        sleep(1000);

        // 返回详情页
        driver.pressKey(new KeyEvent(AndroidKey.BACK));
    }

    private static void scrollToLoadMore(WebElement container) {
        // 6. 滚动加载更多
        Dimension size = driver.manage().window().getSize();
        int startY = (int) (size.height * 0.8);
        int endY = (int) (size.height * 0.2);
        int centerX = size.width / 2;

        new TouchAction<>(driver)
                .press(PointOption.point(centerX, startY))
                .waitAction(WaitOptions.waitOptions(Duration.ofMillis(1000)))
                .moveTo(PointOption.point(centerX, endY))
                .release()
                .perform();

        sleep(3000); // 等待加载
    }

    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void test(){
        try {

            // d. 进入评价页查看带图/视频评价
            driver.findElement(AppiumBy.accessibilityId("评价")).click();
            driver.findElement(AppiumBy.accessibilityId("查看全部")).click();

            // 等待评价页面加载
            new WebDriverWait(driver, Duration.ofSeconds(10))
                    .until(ExpectedConditions.presenceOfElementLocated(
                            AppiumBy.xpath("//android.widget.TextView[contains(@text, '带图') or contains(@text, '视频')]")
                    ));

            // e. 检测并保存高质量图片
            List<WebElement> images = driver.findElements(AppiumBy.className("android.widget.ImageView"));
            for (int i = 0; i < Math.min(images.size(), 3); i++) { // 保存前3张
                File screenshot = images.get(i).getScreenshotAs(OutputType.FILE);
                saveImage(screenshot, "review_image_" + i + ".png");
            }

            // f. 创建笔记
            driver.findElement(AppiumBy.xpath("//android.widget.TextView[@text='发笔记']")).click();

            // 等待笔记编辑页面
            new WebDriverWait(driver, Duration.ofSeconds(5))
                    .until(ExpectedConditions.presenceOfElementLocated(
                            AppiumBy.id("com.dianping.v1:id/editor_container")
                    ));

            // 添加截图
            driver.findElement(AppiumBy.id("com.dianping.v1:id/add_image_btn")).click();
            driver.findElement(AppiumBy.xpath("//android.widget.TextView[@text='从相册选择']")).click();
            // 这里需要实际的文件选择操作，简化处理
            Thread.sleep(2000);

            // g. 生成拼图并选择话题
            driver.findElement(AppiumBy.id("com.dianping.v1:id/puzzle_btn")).click();
            driver.findElement(AppiumBy.id("com.dianping.v1:id/topic_selection")).click();
            driver.findElement(AppiumBy.xpath("//android.widget.TextView[@text='美食推荐']")).click();

            // h. 保存为草稿
            driver.findElement(AppiumBy.id("com.dianping.v1:id/save_draft_btn")).click();
            new WebDriverWait(driver, Duration.ofSeconds(3))
                    .until(ExpectedConditions.presenceOfElementLocated(
                            AppiumBy.xpath("//android.widget.Toast[@text='已保存到草稿']")
                    ));

            // i. 返回商户列表
            // 先返回笔记编辑页
            driver.pressKey(new KeyEvent(AndroidKey.BACK));
            // 再返回详情页
            driver.pressKey(new KeyEvent(AndroidKey.BACK));
            // 最后返回列表页
            driver.findElement(AppiumBy.accessibilityId("Navigate up")).click();

            // j. 等待列表页加载
            new WebDriverWait(driver, Duration.ofSeconds(10))
                    .until(ExpectedConditions.presenceOfElementLocated(
                            AppiumBy.id("com.dianping.v1:id/recycler_view")
                    ));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }

    private static void saveImage(File imageFile, String fileName) throws IOException {
        Path destination = Paths.get("screenshots", fileName);
        Files.createDirectories(destination.getParent());
        Files.copy(imageFile.toPath(), destination);
    }
}